package com.lty.jeeg.server.modules.fas.service.impl;

import com.lty.jeeg.server.common.constant.BizConstant;
import com.lty.jeeg.server.common.enums.ResponseEnum;
import com.lty.jeeg.server.common.page.table.PageTableHandler;
import com.lty.jeeg.server.common.page.table.PageTableRequest;
import com.lty.jeeg.server.common.page.table.PageTableResponse;
import com.lty.jeeg.server.common.utils.BeanConverter;
import com.lty.jeeg.server.modules.fas.dao.*;
import com.lty.jeeg.server.modules.fas.dto.GoodsCategoryDTO;
import com.lty.jeeg.server.modules.fas.dto.GoodsDTO;
import com.lty.jeeg.server.modules.fas.model.*;
import com.lty.jeeg.server.modules.fas.service.GoodsCategoryService;
import com.lty.jeeg.server.modules.fas.service.OrderDetailService;
import com.lty.jeeg.server.modules.sys.dao.DeptDao;
import com.lty.jeeg.server.modules.sys.dao.UserDao;
import com.lty.jeeg.server.modules.sys.model.Dept;
import com.lty.jeeg.server.modules.sys.model.User;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * @author : zl
 * @date : 2019-02-17 09:18:29
 * Description : 采购明细
 */
@Service
@Slf4j
public class OrderDetailServiceImpl implements OrderDetailService {

    private final OrderDetailDao orderDetailDao;
    private final HandOverDao handOverDao;
    private final OrderDao orderDao;
    private final UserDao userDao;
    private final GoodsDao goodsDao;
    private final StockDao stockDao;
    private final DeptDao deptDao;
    private final GoodsCategoryService goodsCategoryService;

    @Autowired
    public OrderDetailServiceImpl(OrderDetailDao orderDetailDao, HandOverDao handOverDao, OrderDao orderDao, UserDao userDao, GoodsDao goodsDao, StockDao stockDao, DeptDao deptDao, GoodsCategoryService goodsCategoryService) {
        this.orderDetailDao = orderDetailDao;
        this.handOverDao = handOverDao;
        this.orderDao = orderDao;
        this.userDao = userDao;
        this.goodsDao = goodsDao;
        this.stockDao = stockDao;
        this.deptDao = deptDao;
        this.goodsCategoryService = goodsCategoryService;
    }

    @Override
    public OrderDetail getById(Long id) {
        return orderDetailDao.getById(id);
    }

    @Override
    public List<OrderDetail> getByorderId(Long orderId) {
        return orderDetailDao.getByorderId(orderId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int delete(Long id) {
        log.debug("删除OrderDetail=>{}", id);
        return orderDetailDao.delete(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int update(OrderDetail orderDetail) {
        orderDetail.preUpdate();
        log.debug("修改OrderDetail=>{}", orderDetail.getId());
        return orderDetailDao.update(orderDetail);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long save(OrderDetail orderDetail) {
        orderDetail.preInsert();
        orderDetailDao.save(orderDetail);
        log.debug("新增OrderDetail=>{}", orderDetail.getId());
        return orderDetail.getId();
    }

    @Override
    public PageTableResponse list(PageTableRequest request) {
        return new PageTableHandler(
                request1 -> orderDetailDao.count(request1.getParams()),
                request2 -> orderDetailDao.list(
                        request2.getParams(), request2.getOffset(), request2.getLimit()))
                .handle(request);
    }

    @Override
    public int changeType(Long id, String type) {
        return orderDetailDao.changeType(id, type);
    }

    @Override
    public List<OrderDetail> findOrderDetailListByOrderId(Long orderId) {
        return orderDetailDao.findOrderDetailListByOrderId(orderId);
    }

    /**
     * 需求单交付
     * @param request
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseEnum deliver(HttpServletRequest request) {
        //需求明细Id
        String orderDetailId = request.getParameter("orderDetailId");
        //交付数量
        String quantity = request.getParameter("quantity");
        //交付人Id
        String delivererId = request.getParameter("delivererId");
        //交付人姓名
        String delivererName = request.getParameter("delivererName");
        //交付状态
        String deliveryStatus = request.getParameter("type");
        //备注
        String remarks = request.getParameter("remark");
        if (StringUtils.isNotBlank(orderDetailId)) {
            //获取需求明细信息
            OrderDetail orderDetail = orderDetailDao.getById(Long.valueOf(orderDetailId));

            if (orderDetail != null) {
                //交付数量类型转换
                Integer quantityInt = Integer.valueOf(quantity);
                //获取该明细待交付数量
                Integer waitNum = orderDetail.getWaitNum();
                //已交付数量为交付数量
                orderDetail.setActNum(quantityInt + orderDetail.getActNum());
                //待交付数量为需求数量减去已交付数量
                orderDetail.setWaitNum(orderDetail.getWaitNum() - quantityInt);
                //判断是否有交付人
                if (StringUtils.isNotBlank(delivererId) && StringUtils.isNotBlank(delivererName)) {
                    orderDetail.setDelivererId(Long.parseLong(delivererId));
                    orderDetail.setDelivererName(delivererName);
                }

                //若之前交付过，追加备注
                orderDetail.setRemark(orderDetail.getRemark() + remarks);

                //判断需求明细是否为空
                //获取需求主单ID
                Long orderId = orderDetail.getOrderId();
                //判断需求主单是否为空
                if (orderId != null && orderId != 0) {
                    //获取需求主单信息
                    Order order = orderDao.getById(orderId);
                    //判断需求主单不为空
                    if (order != null && order.getId() != null) {
                        //待交付数量不为空
                        if (!StringUtils.isEmpty(quantity)) {
                            try {
                                //判断当前需求明细是领用还是采购(采购创建两条记录,领用创建一条记录)
                                Integer demandType = orderDetail.getDemandType();
                                if (demandType != null) {
                                    //需求明细为领取  demandType 10：领取  20: 采购
                                    if (OrderDetail.DemandType.RECEIVE.getCode().equals(demandType)) {
                                        //领用创建一条调拨明细记录
                                        //行政仓
                                        Dept fromDept = deptDao.getById(BizConstant.FAS_ADMIN_STORE_DEPT_ID);
                                        //需求部门
                                        Dept toDept = deptDao.getById(order.getOriginatorOfficeId());
                                        //获取需求明细商品id
                                        Long goodsId = orderDetail.getGoodsId();
                                        //行政仓id
                                        Long fromDeptId = fromDept.getId();
                                        //需求部门Id
                                        Long toDeptId = toDept.getId();
                                        //需求商品及来源部门不为空
                                        if (goodsId != null && fromDeptId != null) {
                                            //根据需求商品查询行政仓库存
                                            Stock num = stockDao.getByGoodsIdAndDeptId(goodsId, fromDeptId);
                                            if (num != null) {
                                                //行政仓商品库存总数需大于交付数量
                                                if (num.getTotalNumber() >= quantityInt) {
                                                    //更新行政仓该商品库存数量
                                                    Integer sumStock = num.getTotalNumber() - quantityInt;
                                                    num.setTotalNumber(sumStock);
                                                    stockDao.update(num);
                                                } else {
                                                    //商品库存不足
                                                    return ResponseEnum.GOODS_STOCK_ERROR;
                                                }
                                                //根据商品及需求部门查询需求部门库存
                                                if (toDeptId != null) {
                                                    //若填写了交付人查看交付人库存，没有填写交付人，查看需求部门库存
                                                    Stock existStock = getStock(delivererId, delivererName, goodsId, toDeptId);
                                                    //若需求部门有此商品库存，修改
                                                    if (existStock != null) {
                                                        updateStock(quantityInt, existStock);
                                                    } else { //需求部门无此商品库存，新增
                                                        addStock(delivererId, delivererName, orderDetail, quantityInt, toDept);
                                                    }
                                                }
                                            } else {
                                                return ResponseEnum.GOODS_NOT_EXIST;
                                            }
                                        }

                                        //添加出入库记录
                                        HandOver handOver = new HandOver();
                                        saveOutStockRecord(delivererId, delivererName, orderDetail, quantityInt, fromDept, toDept, goodsId, handOver);
                                    }
                                    //采购
                                    else if (OrderDetail.DemandType.BUY.getCode().equals(demandType)) {
                                        //行政仓
                                        Dept adminStore = deptDao.getById(BizConstant.FAS_ADMIN_STORE_DEPT_ID);
                                        //添加出入库记录 ------------- 第一条
                                        HandOver inStockRecord = new HandOver();
                                        Long goodsId = orderDetail.getGoodsId();
                                        saveInStockRecord(orderDetail, quantityInt, adminStore, inStockRecord, goodsId);

                                        //添加出入库记录 ------------- 第二条
                                        HandOver outStockRecord = new HandOver();
                                        BeanConverter.map(inStockRecord, outStockRecord);
                                        //需求部门
                                        Dept demandDept = deptDao.getById(order.getOriginatorOfficeId());
                                        saveOutStockRecord(delivererId, delivererName, orderDetail, quantityInt, adminStore, demandDept, goodsId, outStockRecord);

                                        //获取需求部门Id
                                        Long deptIdFor = demandDept.getId();
                                        //采购入库
                                        if (goodsId != null && deptIdFor != null) {
                                            //查看需求部门采购商品的库存
                                            //若填写了交付人查看交付人库存，没有填写交付人，查看需求部门库存
                                            Stock existStock = getStock(delivererId, delivererName, goodsId, deptIdFor);
                                            //有此商品的库存  修改
                                            if (existStock != null) {
                                                updateStock(quantityInt, existStock);
                                            } else {//无此商品的库存  新增
                                                addStock(delivererId, delivererName, orderDetail, quantityInt, demandDept);
                                            }
                                        }
                                    }
                                }

                                if ("delivered".equals(deliveryStatus)) {
                                    if (quantityInt < waitNum) {
                                        //部分交付:将需求明细状态设置为部分交付状态,将主单状态设置为部分交付状态
                                        orderDetail.setOrderDetailType(OrderDetail.OrderDetailType.PARTIAL_DELIVERY.getCode());
                                        //保存明细
                                        orderDetailDao.update(orderDetail);
                                        order.setOrderType(Order.OrderType.PARTIAL_DELIVERY.getCode());
                                        //保存主单
                                        orderDao.update(order);
                                    } else if (quantityInt.equals(waitNum)) {
                                        //全部交付:将需求明细状态设置为全部交付状态\查询主单明细是否全部全部交付
                                        orderDetail.setOrderDetailType(OrderDetail.OrderDetailType.DELIVERED.getCode());
                                        //保存明细
                                        orderDetailDao.update(orderDetail);
                                        checkOrderType(orderDetail);
                                    } else {
//                                    return new ResponseEnum(100,"交付数量不能大于待交付数量");
                                        return ResponseEnum.ERROR;
                                    }
                                } else {
                                    //平单交付:将需求明细状态设置为平单状态\查询主单明细是否全部全部交付
                                    orderDetail.setOrderDetailType(OrderDetail.OrderDetailType.FORCE_FINISH.getCode());
                                    orderDetail.setWaitNum(0);
                                    //保存明细
                                    orderDetailDao.update(orderDetail);
                                    checkOrderType(orderDetail);
                                }

                            } catch (Exception e) {
                                e.printStackTrace();
                                return ResponseEnum.ERROR;
                            }
                        } else {
//                            msg = "交付数量不能为空";
                            return ResponseEnum.ERROR;
                        }
                    }
                }
            }

        } else {
//            msg = "无此明细";
            return ResponseEnum.ORDER_DETAILS_NOT_EXIST;
        }
        return ResponseEnum.SUCCESS;
    }

    private void updateStock(Integer quantityInt, Stock existStock) {
        Integer sumStock = existStock.getTotalNumber() + quantityInt;
        existStock.setTotalNumber(sumStock);
        stockDao.update(existStock);
    }

    private void saveOutStockRecord(String delivererId, String delivererName, OrderDetail orderDetail, Integer quantityInt, Dept adminStore, Dept demandDept, Long goodsId, HandOver handOver) {
        //设置来源部门
        handOver.setDeployComeId(adminStore.getId());
        handOver.setDeployComeName(adminStore.getName());
        //来源人
        handOver.setHandlerId(null);
        handOver.setHandlerName(null);
        //设置需求部门
        handOver.setDeployForId(demandDept.getId());
        handOver.setDeployForName(demandDept.getName());
        //设置需求人
        if (StringUtils.isNotBlank(delivererId) && StringUtils.isNotBlank(delivererName)) {
            handOver.setDeployForpeoId(Long.parseLong(delivererId));
            handOver.setDeployForpeoName(delivererName);
        }
        setDetails(quantityInt, goodsId, handOver);
        handOver.setDetailNum(BigDecimal.valueOf(quantityInt));
        handOver.setDetailSpec(orderDetail.getDetailSpec());
        handOver.setDetailUnit(orderDetail.getDetailUnit());
        handOver.setRemark(orderDetail.getRemark());
        handOver.setIsDeleted(0);
        handOver.setDetailSpec(orderDetail.getDetailSinprice() + "");
        handOver.setHandleType(orderDetail.getDemandType());
        handOver.preInsert();
        handOverDao.save(handOver);
    }

    private void saveInStockRecord(OrderDetail orderDetail, Integer quantityInt, Dept adminStore, HandOver handOver, Long goodsId) {
        //来源部门
        handOver.setDeployComeId(null);
        handOver.setDeployComeName(null);
        //来源人
        handOver.setHandlerId(null);
        handOver.setHandlerName(null);
        //需求部门
        handOver.setDeployForId(adminStore.getId());
        handOver.setDeployForName(adminStore.getName());
        //需求人
        handOver.setDeployForpeoId(null);
        handOver.setDeployForpeoName(null);
        setDetails(quantityInt, goodsId, handOver);
        handOver.setDetailNum(BigDecimal.valueOf(quantityInt));
        handOver.setDetailSpec(orderDetail.getDetailSpec());
        handOver.setDetailUnit(orderDetail.getDetailUnit());
        handOver.setRemark(orderDetail.getRemark());
        handOver.setIsDeleted(0);
        handOver.setDetailSpec(orderDetail.getDetailSinprice() + "");
        handOver.setHandleType(orderDetail.getDemandType());
        handOver.preInsert();
        handOverDao.save(handOver);
    }

    private Stock getStock(String userId, String userName, Long goodsId, Long deptId) {
        Stock existStock;
        if (StringUtils.isNotBlank(userId) && StringUtils.isNotBlank(userName)) {
            User deliver = userDao.getById(Long.parseLong(userId));
            existStock = stockDao.getCheck(goodsId, deliver.getDept().getId(), Long.parseLong(userId));
        } else {
            existStock = stockDao.getByGoodsIdAndDeptId(goodsId, deptId);
        }
        return existStock;
    }

    private void addStock(String delivererId, String delivererName, OrderDetail orderDetail, Integer quantityInt, Dept dept) {
        Stock newStock = new Stock();
        Goods smGoods = goodsDao.getById(orderDetail.getGoodsId());
        newStock.setGoodsId(orderDetail.getId());
        //添加商品分类父级
        newStock.setCategory(smGoods.getCategory());
        newStock.setDeptId(dept.getId());
        if (StringUtils.isNotBlank(delivererId) && StringUtils.isNotBlank(delivererName)) {
            newStock.setUserId(Long.parseLong(delivererId));
        }
        newStock.setCompanyId(orderDetail.getCompanyId());
        //库存数量为已交付数量
        newStock.setTotalNumber(quantityInt);
        //闲置数量默认为0
        newStock.setIdleNumber(0);
        GoodsDTO goodsDTO = goodsDao.getById(newStock.getGoodsId());
        GoodsCategoryDTO goodsCategoryDTO = goodsCategoryService.getById(goodsDTO.getCategory());
        newStock.setParentCategory(goodsCategoryDTO.getParentId());
        newStock.preInsert();
        stockDao.save(newStock);
    }

    private void setDetails(Integer quantityInt, Long goodsId, HandOver smHandOver) {
        if (goodsId != null) {
            Goods smGoods = goodsDao.getById(goodsId);
            smHandOver.setGoodsId(goodsId);
            smHandOver.setGoodsName(smGoods.getName());
            //若是单价为空，总价默认为0
            if (smGoods.getUnitPrice() != null) {
                smHandOver.setUnitPrice(smGoods.getUnitPrice());
                smHandOver.setTotalPrice(smGoods.getUnitPrice().multiply(BigDecimal.valueOf(quantityInt)));
            } else {
                smHandOver.setUnitPrice(BigDecimal.valueOf(0));
                smHandOver.setTotalPrice(BigDecimal.valueOf(0));
            }
        }
    }

    @Override
    public void checkOrderType(OrderDetail smOrderDetail) {
        if (smOrderDetail != null && smOrderDetail.getOrderId() != null) {
            //获取主单Id
            Long orderId = smOrderDetail.getOrderId();
            //获取主单信息
            Order smOrder = orderDao.getById(orderId);
            //获取主单下的需求明细详情
            List<OrderDetail> orderDetailList = orderDetailDao.findOrderDetailListByOrderId(orderId);
            //遍历明细需求单详情
            if (orderDetailList != null && orderDetailList.size() > 0) {
                //是否全部交付
                boolean isAllDeliver = true;
                for (OrderDetail orderDetail : orderDetailList) {
                    if (orderDetail != null && orderDetail.getOrderDetailType() != null) {
                        //获取需求明细单状态
                        Integer orderDetailType = orderDetail.getOrderDetailType();
                        //明细状态为全部交付，取消，平单时返回false
                        if (!(OrderDetail.OrderDetailType.DELIVERED.getCode().equals(orderDetailType)
                                || OrderDetail.OrderDetailType.CANCELED.getCode().equals(orderDetailType)
                                || OrderDetail.OrderDetailType.FORCE_FINISH.getCode().equals(orderDetailType))) {
                            isAllDeliver = false;
                        }
                    }
                }

                if (isAllDeliver) {
                    //主单设置为全部交付
                    smOrder.setOrderType(Order.OrderType.DELIVERED.getCode());
                    //设置交付时间
                    smOrder.setDeliveryDate(new Date());
                } else {
                    //主单设置为部分交付
                    smOrder.setOrderType(Order.OrderType.PARTIAL_DELIVERY.getCode());
                }
                orderDao.update(smOrder);
            }
        }
    }

    @Override
    public ResponseEnum cancel(Long id) {
        if (id != null) {
            OrderDetail smOrderDetail = orderDetailDao.getById(id);
            if (smOrderDetail != null && smOrderDetail.getId() != null) {
                smOrderDetail.setOrderDetailType(OrderDetail.OrderDetailType.CANCELED.getCode());
                smOrderDetail.setWaitNum(0);
                orderDetailDao.update(smOrderDetail);
                checkOrderType(smOrderDetail);
            }
            return ResponseEnum.SUCCESS;
        } else {
            return ResponseEnum.ERROR;
        }
    }


}
